#pragma once
#include "TcpServer.hpp"
#include "HttpProtocol.hpp"
#include <cstdio>

namespace HttpServerModule
{
    using namespace TcpServerModule;
    using func_t = std::function<std::string(Request& req,Response&res)>;
    const uint16_t gport = 8081;
    class HttpServer
    {
    private:
        std::shared_ptr<TcpServer> _tsvr;
        std::unordered_map<std::string,func_t> _TaskWayQ;
        bool CheckSafe(const std::string&s)
        {
            return( _TaskWayQ.find(s) != _TaskWayQ.end());
        }
        void Handler(SockPtr ret, InetAddr &client)
        {
            std::string result_str;
            std::string buffer;
            while(true)
            {
                std::string message;
                int n = ret->ToRecv(&buffer);
                if (n > 0)
                {
                    while(Decode(buffer,&message))
                    {
                        //进行处理
                        Request req;
                        req.Deserilize(message);
                        //for test
                        // req.DebugPrint();
                        Response res;
                        if (req.IsHaveArgs())
                        {
                            if (CheckSafe(req.GetTask()))
                            {
                                result_str += _TaskWayQ[req.GetTask()](req,res);
                            }
                            else 
                            {
                                result_str += res.Build(req);
                            }
                        }
                        else 
                        {
                            result_str += res.Build(req);
                        }
                        // std::string result = res.Build(req);
                    }
                    break;
                }
                else if (n == 0){
                    LOG(LogLevel::INFO) << "写端退出";
                    break;
                }
                else 
                {
                    if (errno == EAGAIN){
                        LOG(LogLevel::INFO) << "数据没准备好呢";
                        break;
                    }
                    else if(errno == EINTR){
                        //被信号打断，继续读取
                        continue;
                    }
                    else 
                    {   
                        break;
                    }
                }
            }
            ret->ToSend(result_str);
        }
    public:
        void RegisterHandler(const std::string& method,func_t func)
        {   
            _TaskWayQ[method] = func;
        }
        HttpServer(uint16_t port = gport)
            : _tsvr(std::make_shared<TcpServer>(port))
        {
            _tsvr->RegisterHandler([&](SockPtr ret, InetAddr client)
                                   { return this->Handler(ret, client); });
        }
        void Start()
        {
            _tsvr->Loop();
        }

        ~HttpServer() {}
    };
}
